package me.ydq.core.table;

import me.ydq.mapper.Mapping;
import me.ydq.misc.Fn;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.SingleColumnRowMapper;

import java.util.Map;

public interface TableUnique<T> extends TableBase<T> {


    <R> R unique(Map<Fn<T, ?>, Object> equalConditions, RowMapper<R> rowMapper);

    default T unique() {
        return unique(Map.of(), rowMapper());
    }

    default T unique(Fn<T, ?> column, Object value) {
        return unique(Map.of(column, value), rowMapper());
    }

    default T unique(Fn<T, ?> column1, Object value1, Fn<T, ?> column2, Object value2) {
        return unique(Map.of(column1, value1, column2, value2), rowMapper());
    }

    default T unique(Fn<T, ?> column1, Object value1, Fn<T, ?> column2, Object value2, Fn<T, ?> column3, Object value3) {
        return unique(Map.of(column1, value1, column2, value2, column3, value3), rowMapper());
    }

    default T unique(Map<Fn<T, ?>, Object> equalConditions) {
        return unique(equalConditions, rowMapper());
    }

    default <R> R unique(RowMapper<R> rowMapper) {
        return unique(Map.of(), rowMapper);
    }

    default <R> R unique(Fn<T, ?> column, Object value, RowMapper<R> rowMapper) {
        return unique(Map.of(column, value), rowMapper);
    }

    default <R> R unique(Fn<T, ?> column1, Object value1, Fn<T, ?> column2, Object value2, RowMapper<R> rowMapper) {
        return unique(Map.of(column1, value1, column2, value2), rowMapper);
    }

    default <R> R unique(Fn<T, ?> column1, Object value1, Fn<T, ?> column2, Object value2, Fn<T, ?> column3, Object value3, RowMapper<R> rowMapper) {
        return unique(Map.of(column1, value1, column2, value2, column3, value3), rowMapper);
    }

    default <R> R unique(Mapping<R> mapping) {
        return unique(Map.of(), (rs, i) -> mapping.map(rs));
    }

    default <R> R unique(Fn<T, ?> column, Object value, Mapping<R> mapping) {
        return unique(Map.of(column, value), (rs, i) -> mapping.map(rs));
    }

    default <R> R unique(Fn<T, ?> column1, Object value1, Fn<T, ?> column2, Object value2, Mapping<R> mapping) {
        return unique(Map.of(column1, value1, column2, value2), (rs, i) -> mapping.map(rs));
    }

    default <R> R unique(Fn<T, ?> column1, Object value1, Fn<T, ?> column2, Object value2, Fn<T, ?> column3, Object value3, Mapping<R> mapping) {
        return unique(Map.of(column1, value1, column2, value2, column3, value3), (rs, i) -> mapping.map(rs));
    }

    default <R> R unique(Map<Fn<T, ?>, Object> equalConditions, Mapping<R> mapping) {
        return unique(equalConditions, (rs, i) -> mapping.map(rs));
    }

    default <R> R unique(Class<R> returnType) {
        return unique(Map.of(), new SingleColumnRowMapper<>(returnType));
    }

    default <R> R unique(Fn<T, ?> column, Object value, Class<R> returnType) {
        return unique(Map.of(column, value), new SingleColumnRowMapper<>(returnType));
    }

    default <R> R unique(Fn<T, ?> column1, Object value1, Fn<T, ?> column2, Object value2, Class<R> returnType) {
        return unique(Map.of(column1, value1, column2, value2), new SingleColumnRowMapper<>(returnType));
    }

    default <R> R unique(Fn<T, ?> column1, Object value1, Fn<T, ?> column2, Object value2, Fn<T, ?> column3, Object value3, Class<R> returnType) {
        return unique(Map.of(column1, value1, column2, value2, column3, value3), new SingleColumnRowMapper<>(returnType));
    }

    default <R> R unique(Map<Fn<T, ?>, Object> equalConditions, Class<R> returnType) {
        return unique(equalConditions, new SingleColumnRowMapper<>(returnType));
    }

}
